#include"Solution.h"
#include"Evaluation.h"
#include"RandomGenerator.h"

using namespace std;

Solution::Solution(int n):_haveEvaluate(false){
	if( n > 0 ){
		for( int i = 0 ; i < n ; i++ ){
			_solution.push_back(0);
		}
	}
}

Solution::Solution(const vector<int>& solution):_haveEvaluate(false){
	if( solution.size() > 0 ){
		for( int i = 0 ; i < solution.size() ; i++ ){
			_solution.push_back(solution[i]);
		}
	}
	else{
		for( int i = 0 ; i < solution.size() ; i++ ){
			_solution.push_back(0);
		}
	}
}

int Solution::getEvaluate(){
	if(_haveEvaluate){
		return _evaluate;
	}
	else{
		_evaluate = Evaluation::Evaluate(*this);
		_haveEvaluate = true;
		return _evaluate;
	}
}

Solution Solution::getRandomNeighbor() const
{
	RandomGen<int> random(0 , Evaluation::GetJobNum() - 1);
	int integerToMove;
	while(true)
	{
		int movingIndex = random();
		int insertingIndex = random();
		if(movingIndex != insertingIndex)
		{
			return getNeighbor(movingIndex , insertingIndex);
			break;
		}
	}
}

Solution Solution::getNeighbor(const int& movingIndex , const int& insertingIndex) const
{
	Solution neighbor(*this);
	int movingJob = neighbor[movingIndex];
	if(movingIndex != insertingIndex)
	{
		int integerToMove = neighbor[movingIndex];
		if(insertingIndex < movingIndex)
		{
			for(int index = movingIndex ; index > insertingIndex ; --index)
			{
				neighbor[index] = neighbor[index - 1];
			}
		}
		else//insertingIndex > movingIndex
		{
			for(int index = movingIndex ; index < insertingIndex ; ++index)
			{
				neighbor[index] = neighbor[index + 1];
			}
		}
		neighbor[insertingIndex] = movingJob;
	}
	return neighbor;
}

bool Solution::operator<(Solution& anotherSolution)
{
	return getEvaluate() < anotherSolution.getEvaluate();
}